﻿using Microsoft.Ajax.Utilities;

namespace Framework.Mvc.Util
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.IO;
    using System.Text;
    using Common;
    /// <summary>
    /// CombineFiles 的摘要说明
    /// </summary>
    public class CombineFiles
    {
        /// <summary>
        /// 获取文件绝对路径
        /// </summary>
        /// <param name="filesrc"></param>
        /// <param name="fileExt"></param>
        /// <returns></returns>
        private static IEnumerable<string> GetFilePath(string filesrc, string fileExt)
        {
            return filesrc.Split(',').Select(i => PathHelper.MapPath("/" + i + "." + fileExt));
        }


        class CacheItem
        {
            public string Content { set; get; }
            public DateTime Expires { set; get; }
        }

        /// <summary>
        /// 压缩类型
        /// </summary>
        public enum CompressType
        {
            Css,
            Js
        }

        /// <summary>
        /// 压缩
        /// </summary>
        /// <param name="type"></param>
        public static void Compress(CompressType type)
        {
            string cacheKey;
            switch (type)
            {
                case CompressType.Js:
                    HttpContext.Current.Response.ContentType = "text/javascript";
                    cacheKey = HttpContext.Current.Request.Url.Query + ".js";
                    break;
                case CompressType.Css:
                    HttpContext.Current.Response.ContentType = "text/css";
                    cacheKey = HttpContext.Current.Request.Url.Query + ".css";
                    break;
                default:
                    cacheKey = "NotFound";
                    break;
            }
            CacheItem cacheItem = HttpRuntime.Cache.Get(cacheKey) as CacheItem;
            if (cacheItem == null)
            {
                var sb = new StringBuilder(); //用于合并的内容
                string href = RequestExtention.GetString("href"); //用于压缩的js/css文件源
                var minifier = new Minifier(); //minifier对象
                Func<string, string> compressFunc = null;
                IEnumerable<string> fileNames = null;
                switch (type)
                {
                    case CompressType.Js:
                        fileNames = GetFilePath(href, "js");
                        compressFunc = minifier.MinifyJavaScript;
                        break;
                    case CompressType.Css:
                        fileNames = GetFilePath(href, "css");
                        compressFunc = minifier.MinifyStyleSheet;
                        break;
                }
                if (fileNames.IsNotNullOrEmpty())
                {
                    fileNames.Each(fileName =>
                    {
                        try
                        {
                            if (File.Exists(fileName))
                            {
                                string readstr = File.ReadAllText(fileName, Encoding.UTF8);
                                sb.Append(readstr);
                            }
                        }
                        catch (Exception ex)
                        {
                            LogHelper.Fatal("file can not found :" + fileName, ex);
                        }
                    });
                }
                if (compressFunc != null)
                {
                    string content = compressFunc(sb.ToString());
                    cacheItem = new CacheItem { Content = content, Expires = DateTime.Now.AddHours(24) };
                    HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, cacheItem.Expires, TimeSpan.Zero);
                }
            }
            if (cacheItem != null)
            {
                if (HttpContext.Current.Request.Headers["If-Modified-Since"] != null &&
                    TimeSpan.FromTicks(cacheItem.Expires.Ticks - DateTime.Parse(HttpContext.Current.Request.Headers["If-Modified-Since"]).Ticks).Seconds < 100)
                {
                    HttpContext.Current.Response.StatusCode = 304;
                    // response.Headers.Add("Content-Encoding", "gzip"); 
                    HttpContext.Current.Response.StatusDescription = "Not Modified";
                }
                else
                {
                    HttpContext.Current.Response.Write(cacheItem.Content);
                    //Set ETag
                    HttpContext.Current.Response.Cache.SetETag(DateTime.Now.Ticks.ToString());
                    //SetLastModified
                    HttpContext.Current.Response.Cache.SetLastModified(DateTime.Now);
                    //public 以指定响应能由客户端和共享（代理）缓存进行缓存。   
                    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
                    //是允许文档在被视为陈旧之前存在的最长绝对时间。   
                    HttpContext.Current.Response.Cache.SetMaxAge(new TimeSpan(7, 0, 0, 0));
                    //将缓存过期从绝对时间设置为可调时间   
                    HttpContext.Current.Response.Cache.SetSlidingExpiration(true);
                }
            }
        }
    }
}
